package com.ruoyi.system.service.impl;

import java.util.List;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.GenConstants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
//import com.ruoyi.generator.util.GenUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.DocGenTableColumn;
import com.ruoyi.system.mapper.DocGenTableColumnMapper;
import com.ruoyi.system.utils.GenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.DocGenTableMapper;
import com.ruoyi.system.domain.DocGenTable;
import com.ruoyi.system.service.IDocGenTableService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 代码生成业务Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-10-11
 */
@Service
public class DocGenTableServiceImpl implements IDocGenTableService
{
    @Autowired
    private DocGenTableMapper docGenTableMapper;
    @Autowired
    private DocGenTableColumnMapper docGenTableColumnMapper;

    /**
     * 查询业务信息
     *
     * @param id 业务ID
     * @return 业务信息
     */
    @Override
    public DocGenTable selectDocGenTableById(Long id)
    {
        DocGenTable docGenTable = docGenTableMapper.selectDocGenTableById(id);
        setTableFromOptions(docGenTable);
        return docGenTable;
        //return docGenTable;
    }

    /**
     * 查询代码生成业务
     * 
     * @param tableId 代码生成业务主键
     * @return 代码生成业务
     */
    @Override
    public DocGenTable selectDocGenTableByTableId(Long tableId)
    {
        return docGenTableMapper.selectDocGenTableByTableId(tableId);
    }

    /**
     * 查询代码生成业务列表
     * 
     * @param docGenTable 代码生成业务
     * @return 代码生成业务
     */
    @Override
    public List<DocGenTable> selectDocGenTableList(DocGenTable docGenTable)
    {
        return docGenTableMapper.selectDocGenTableList(docGenTable);
    }

    /**
     * 新增代码生成业务
     * 
     * @param docGenTable 代码生成业务
     * @return 结果
     */
    @Override
    public int insertDocGenTable(DocGenTable docGenTable)
    {
        docGenTable.setCreateTime(DateUtils.getNowDate());
        return docGenTableMapper.insertDocGenTable(docGenTable);
    }

    /**
     * 修改代码生成业务
     * 
     * @param docGenTable 代码生成业务
     * @return 结果
     */
    @Override
    public int updateDocGenTable(DocGenTable docGenTable)
    {
        docGenTable.setUpdateTime(DateUtils.getNowDate());
        return docGenTableMapper.updateDocGenTable(docGenTable);
    }

    /**
     * 同步数据库
     *
     * @param tableName 表名称
     */
    @Override
    @Transactional
    public void synchDb(String tableName)
    {
        DocGenTable table = docGenTableMapper.selectDocGenTableByName(tableName);
        List<DocGenTableColumn> tableColumns = table.getColumns();
        List<String> tableColumnNames = tableColumns.stream().map(DocGenTableColumn::getColumnName).collect(Collectors.toList());

        List<DocGenTableColumn> dbTableColumns = docGenTableColumnMapper.selectDbTableColumnsByName(tableName);
        if (StringUtils.isEmpty(dbTableColumns))
        {
            throw new ServiceException("同步数据失败，原表结构不存在");
        }
        List<String> dbTableColumnNames = dbTableColumns.stream().map(DocGenTableColumn::getColumnName).collect(Collectors.toList());

        dbTableColumns.forEach(column -> {
            if (!tableColumnNames.contains(column.getColumnName()))
            {
                GenUtils.initColumnField(column, table);
                docGenTableColumnMapper.insertDocGenTableColumn(column);
            }
        });

        List<DocGenTableColumn> delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(delColumns))
        {
            docGenTableColumnMapper.deleteDocGenTableColumns(delColumns);
        }
    }

    /**
     * 批量删除代码生成业务
     * 
     * @param tableIds 需要删除的代码生成业务主键
     * @return 结果
     */
    @Override
    public int deleteDocGenTableByTableIds(Long[] tableIds)
    {
        return docGenTableMapper.deleteDocGenTableByTableIds(tableIds);
    }

    /**
     * 删除代码生成业务信息
     * 
     * @param tableId 代码生成业务主键
     * @return 结果
     */
    @Override
    public int deleteDocGenTableByTableId(Long tableId)
    {
        return docGenTableMapper.deleteDocGenTableByTableId(tableId);
    }


    /**
     * 修改保存参数校验
     *
     * @param docGenTable 业务信息
     */
    @Override
    public void validateEdit(DocGenTable docGenTable)
    {
        if (GenConstants.TPL_TREE.equals(docGenTable.getTplCategory()))
        {
            String options = JSON.toJSONString(docGenTable.getParams());
            JSONObject paramsObj = JSONObject.parseObject(options);
            if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE)))
            {
                throw new ServiceException("树编码字段不能为空");
            }
            else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE)))
            {
                throw new ServiceException("树父编码字段不能为空");
            }
            else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME)))
            {
                throw new ServiceException("树名称字段不能为空");
            }
            else if (GenConstants.TPL_SUB.equals(docGenTable.getTplCategory()))
            {
                if (StringUtils.isEmpty(docGenTable.getSubTableName()))
                {
                    throw new ServiceException("关联子表的表名不能为空");
                }
                else if (StringUtils.isEmpty(docGenTable.getSubTableFkName()))
                {
                    throw new ServiceException("子表关联的外键名不能为空");
                }
            }
        }
    }

    /**
     * 修改表信息
     *
     * @param docGenTable 业务信息
     * @return 结果
     */
    @Override
    @Transactional
    public void updateGenTable(DocGenTable docGenTable)
    {
        String options = JSON.toJSONString(docGenTable.getParams());
        docGenTable.setOptions(options);
        int row = docGenTableMapper.updateDocGenTable(docGenTable);
        if (row > 0)
        {
            // 循环每一列
            for (DocGenTableColumn cenTableColumn : docGenTable.getColumns())
            {
                docGenTableColumnMapper.updateDocGenTableColumn(cenTableColumn);
            }
        }
    }

    /**
     * 查询所有表信息
     *
     * @return 表信息集合
     */
    @Override
    public List<DocGenTable> selectDocGenTableAll()
    {
        return docGenTableMapper.selectDocGenTableAll();
    }

    /**
     * 查询据库列表
     *
     * @param docGenTable 业务信息
     * @return 数据库表集合
     */
    @Override
    public List<DocGenTable> selectDbTableList(DocGenTable docGenTable) {
        return docGenTableMapper.selectDbTableList(docGenTable);
    }

    /**
     * 导入表结构
     *
     * @param tableList 导入表列表
     */
    @Override
    @Transactional
    public void importDocGenTable(List<DocGenTable> tableList)
    {
        String operName = SecurityUtils.getUsername();
        try
        {
            for (DocGenTable table : tableList)
            {
                String tableName = table.getTableName();
                GenUtils.initTable(table, operName);
                int row = docGenTableMapper.insertDocGenTable(table);
                if (row > 0)
                {
                    // 保存列信息
                    List<DocGenTableColumn> docGenTableColumns = docGenTableColumnMapper.selectDbTableColumnsByName(tableName);
                    for (DocGenTableColumn column : docGenTableColumns)
                    {
                        GenUtils.initColumnField(column, table);
                        docGenTableColumnMapper.insertDocGenTableColumn(column);
                    }
                }
            }
        }
        catch (Exception e)
        {
            throw new ServiceException("导入失败：" + e.getMessage());
        }
    }

    /**
     * 查询据库列表
     *
     * @param tableNames 表名称组
     * @return 数据库表集合
     */
    @Override
    public List<DocGenTable> selectDbTableListByNames(String[] tableNames)
    {
        return docGenTableMapper.selectDbTableListByNames(tableNames);
    }

    /**
     * 设置代码生成其他选项值
     *
     * @param docGenTable 设置后的生成对象
     */
    public void setTableFromOptions(DocGenTable docGenTable)
    {
        JSONObject paramsObj = JSONObject.parseObject(docGenTable.getOptions());
        if (StringUtils.isNotNull(paramsObj))
        {
            String treeCode = paramsObj.getString(GenConstants.TREE_CODE);
            String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE);
            String treeName = paramsObj.getString(GenConstants.TREE_NAME);
            String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID);
            String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME);

            docGenTable.setTreeCode(treeCode);
            docGenTable.setTreeParentCode(treeParentCode);
            docGenTable.setTreeName(treeName);
            docGenTable.setParentMenuId(parentMenuId);
            docGenTable.setParentMenuName(parentMenuName);
        }
    }

}
